<template>
  <div
    class="carousel-container"
    @mouseenter="showControls = true"
    @mouseleave="showControls = false"
  >
    <div class="carousel" ref="carouselRef">
      <div class="carousel-track" :style="trackStyle">
        <div
          v-for="(image, index) in images"
          :key="index"
          class="carousel-slide"
        >
          <img
            :src="image"
            :alt="`轮播图 ${index + 1}`"
            class="carousel-image"
            :style="imageStyle"
          />
        </div>
      </div>

      <!-- 导航按钮 -->
      <div
        class="carousel-btn prev"
        :class="{ show: showControls }"
        @click="prevSlide"
      >
        <svg width="1.5rem" height="1.5rem" viewBox="0 0 24 24" fill="none">
          <path
            d="M15 18L9 12L15 6"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
        </svg>
      </div>
      <div
        class="carousel-btn next"
        :class="{ show: showControls }"
        @click="nextSlide"
      >
        <svg width="1.5rem" height="1.5rem" viewBox="0 0 24 24" fill="none">
          <path
            d="M9 18L15 12L9 6"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
        </svg>
      </div>

      <!-- 指示器 - 始终显示 -->
      <div class="carousel-indicators">
        <div
          v-for="index in images.length"
          :key="index"
          class="indicator"
          :class="{ active: currentIndex === index - 1 }"
          @click="goToSlide(index - 1)"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'

interface Props {
  images: string[]
  borderRadius?: string
  autoPlay?: boolean
  interval?: number
  height?: string
}

const props = withDefaults(defineProps<Props>(), {
  images: () => [],
  borderRadius: '0.5rem',
  autoPlay: true,
  interval: 3000,
  height: '29.6875rem',
})

const currentIndex = ref(0)
const showControls = ref(false)
let autoPlayTimer: number | null = null

// 计算属性
const trackStyle = computed(() => ({
  transform: `translateX(-${currentIndex.value * 100}%)`,
}))

const imageStyle = computed(() => ({
  borderTopLeftRadius: props.borderRadius,
  borderBottomLeftRadius: props.borderRadius,
}))

// 方法
const nextSlide = () => {
  currentIndex.value = (currentIndex.value + 1) % props.images.length
}

const prevSlide = () => {
  currentIndex.value =
    (currentIndex.value - 1 + props.images.length) % props.images.length
}

const goToSlide = (index: number) => {
  currentIndex.value = index
}

const startAutoPlay = () => {
  if (!props.autoPlay || props.images.length <= 1) return
  stopAutoPlay()
  autoPlayTimer = setInterval(nextSlide, props.interval)
}

const stopAutoPlay = () => {
  if (autoPlayTimer) {
    clearInterval(autoPlayTimer)
    autoPlayTimer = null
  }
}

// 生命周期
onMounted(startAutoPlay)
onUnmounted(stopAutoPlay)
</script>

<style scoped lang="scss">
.carousel-container {
  width: 100%;
  overflow: hidden;
  border-top-left-radius: v-bind('props.borderRadius');
  border-bottom-left-radius: v-bind('props.borderRadius');
}

.carousel {
  position: relative;
  width: 100%;
  height: v-bind('props.height');
  overflow: hidden;
}

.carousel-track {
  display: flex;
  height: 100%;
  transition: transform 0.5s ease;
}

.carousel-slide {
  flex: 0 0 100%;
  min-width: 100%;
}

.carousel-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-top-left-radius: v-bind('props.borderRadius');
  border-bottom-left-radius: v-bind('props.borderRadius');
}

.carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 3rem;
  height: 3rem;
  background: #a1a1a1;
  border: none;
  border-radius: 50%;
  color: #ffffff;
  cursor: pointer;
  z-index: 2;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;

  &.show {
    opacity: 0.5;
    visibility: visible;
  }

  &:hover {
    background: #8a8a8a;
  }

  &.prev {
    left: 1rem;

    svg {
      transform: translateX(-0.1rem);
    }
  }

  &.next {
    right: 1rem;

    svg {
      transform: translateX(0.1rem);
    }
  }

  svg {
    width: 1.5rem;
    height: 1.5rem;
    transition: transform 0.2s ease;
  }
}

.carousel-indicators {
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.5rem;
  z-index: 2;
}

.indicator {
  width: 0.75rem;
  height: 0.75rem;
  border: 0.125rem solid rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: all 0.3s ease;

  &.active {
    background: white;
    border-color: white;
    width: 2.25rem;
    border-radius: 0.375rem;
  }

  &:hover {
    transform: scale(1.2);
  }
}

@media (max-width: 48rem) {
  .carousel-btn {
    width: 2.5rem;
    height: 2.5rem;

    svg {
      width: 1.25rem;
      height: 1.25rem;
    }

    &.prev {
      left: 0.5rem;

      svg {
        transform: translateX(-0.08rem);
      }
    }

    &.next {
      right: 0.5rem;

      svg {
        transform: translateX(0.08rem);
      }
    }
  }

  .carousel-indicators {
    bottom: 0.75rem;
  }

  .indicator {
    width: 0.625rem;
    height: 0.625rem;

    &.active {
      width: 1.5rem;
    }
  }
}
</style>
